#include "qtlcdlabel.h"
#include <QDebug>

QtLCDLabel::QtLCDLabel(QWidget *parent)
          : QLabel(parent)
{

}

void QtLCDLabel::setAutoScroll(bool flags){
    if(flags){
        if(nullptr == m_timer){
            m_timer = new QTimer(this);
            connect(m_timer, &QTimer::timeout, this, [this]() {
                m_scrollOffset += 4;
                // 重绘
                update();
            });
        }
        m_timer->start(50);
    }else{
        if(nullptr != m_timer){
            m_timer->stop();
        }
    }
}

QtLCDLabel::~QtLCDLabel(){

}

void QtLCDLabel::setText(QString text){
    m_textImage = generateDotMatrix(text);
    // 清空点阵图，表示需要重新生成
    m_textDotMatrixImage = QImage();
    update();
}
void QtLCDLabel::resizeEvent(QResizeEvent *pEvent){
    m_backgroundDotMatrixImage = generateBackgroundDotMatrixImage();
    QLabel::resizeEvent(pEvent);
}

QImage QtLCDLabel::generateBackgroundDotMatrixImage()
{
    QImage image(width(), height(), QImage::Format_ARGB32);
    image.fill(m_backgroundColor);

    QPainter painter(&image);
    painter.setRenderHint(QPainter::Antialiasing);

    for (int y = 0; y < height(); y += (m_pixelSize + m_spacingSize))
    {
        for (int x = 0; x < width(); x += (m_pixelSize + m_spacingSize))
        {
            QRect rect(x, y, m_pixelSize, m_pixelSize);
            painter.fillRect(rect, m_pixelColor);
        }
    }

    return image;
}

QImage QtLCDLabel::generateDotMatrix(const QString &text){

    // 1. 基础设置
    QFont font;
    font.setFamily("宋体");
    font.setBold(true);
    // font.setItalic(true);

    // 2. 先粗略估计字体大小，让它能填满控件宽度一定比例
    // 让字体高度大概是控件高度的60%
    // 字号和像素高度大致比例调整一下
    int targetHeight = height() * 0.2;
    int pointSize    = targetHeight / 2.0;
    font.setPointSize(pointSize);

    QFontMetrics fm(font);
    int textWidth = fm.horizontalAdvance(text);
    int textHeight = fm.height();

    if(textWidth <= 0 || textHeight <= 0)
    {
        return QImage();
    }

    // 4. 创建适配的图片
    QImage image(textWidth, textHeight, QImage::Format_ARGB32);
    image.fill(Qt::transparent);

    // 5. 绘制
    QPainter painter(&image);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setFont(font);
    painter.setPen(Qt::white);
    painter.drawText(image.rect(), Qt::AlignLeft | Qt::AlignVCenter, text);
    painter.end();

    return image;
}

QImage QtLCDLabel::generateDotMatrixImage(const QImage& source)
{
    int matrixWidth = source.width() * (m_pixelSize + m_spacingSize) - m_spacingSize;
    int matrixHeight = source.height() * (m_pixelSize + m_spacingSize) - m_spacingSize;

    QImage image(matrixWidth, matrixHeight, QImage::Format_ARGB32);
    image.fill(Qt::transparent);

    QPainter painter(&image);
    painter.setRenderHint(QPainter::Antialiasing);

    for (int y = 0; y < source.height(); ++y)
    {
        for (int x = 0; x < source.width(); ++x)
        {
            QColor pixelColor = source.pixelColor(x, y);
            if (pixelColor.alpha() > 128)
            {
                int rectX = x * (m_pixelSize + m_spacingSize);
                int rectY = y * (m_pixelSize + m_spacingSize);
                QRect rect(rectX, rectY, m_pixelSize, m_pixelSize);
                painter.fillRect(rect, m_textColor);
            }
        }
    }

    return image;
}

void QtLCDLabel::paintEvent(QPaintEvent *pEvent){
    QLabel::paintEvent(pEvent);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    if (!m_backgroundDotMatrixImage.isNull())
        painter.drawImage(0, 0, m_backgroundDotMatrixImage);

    if (m_textImage.isNull())
        return;

    if (m_textDotMatrixImage.isNull())
    {
        m_textDotMatrixImage = generateDotMatrixImage(m_textImage);
    }

    if (!m_textDotMatrixImage.isNull())
    {
        int startX = (width() - m_textDotMatrixImage.width()) / 2;
        int matrixWidth = m_textDotMatrixImage.width();

        if (m_IsAutoScroll && matrixWidth > width())
        {
            startX = -m_scrollOffset;
            if (m_scrollOffset > matrixWidth)
                m_scrollOffset = 0;
        }

        int offsetY = (height() - m_textDotMatrixImage.height()) / 2;
        painter.drawImage(startX, offsetY, m_textDotMatrixImage);
    }
}
